home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / utility1 / gs261src.zip / ZFILTER2.C < prev    next >
C/C++ Source or Header  |  1993-05-13  |  11KB  |  372 lines

  1. /* Copyright (C) 1991, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* zfilter2.c */
  20. /* Additional filter creation for Ghostscript */
  21. #include "memory_.h"
  22. #include "ghost.h"
  23. #include "errors.h"
  24. #include "oper.h"
  25. #include "alloc.h"
  26. #include "dict.h"
  27. #include "dparam.h"
  28. #include "stream.h"
  29. #include "sdct.h"
  30.  
  31. /* Imported from zfilter.c */
  32. int filter_read(P4(os_ptr, const stream_procs _ds *, stream **, uint));
  33. int filter_write(P4(os_ptr, const stream_procs _ds *, stream **, uint));
  34.  
  35. /* Names of keys in CCITTFax filter dictionary: */
  36. static ref name_Uncompressed;
  37. static ref name_K;
  38. static ref name_EndOfLine;
  39. static ref name_EncodedByteAlign;
  40. static ref name_Columns;
  41. static ref name_Rows;
  42. static ref name_EndOfBlock;
  43. static ref name_BlackIs1;
  44. static ref name_DamagedRowsBeforeError;
  45. static ref name_FirstBitLowOrder;
  46. /* Names of (additional) keys in DCT filter dictionary: */
  47. static ref name_Colors;
  48. static ref name_HSamples;
  49. static ref name_VSamples;
  50. static ref name_QuantTables;
  51. static ref name_QFactor;
  52. static ref name_HuffTables;
  53. static ref name_ColorTransform;
  54.  
  55. /* Initialization */
  56. private void
  57. zfilter2_init(void)
  58. {    static const names_def f2n[] = {
  59.  
  60.     /* Create the names of the known entries in */
  61.     /* CCITTFax filter dictionaries. */
  62.        { "Uncompressed", &name_Uncompressed },
  63.        { "K", &name_K },
  64.        { "EndOfLine", &name_EndOfLine },
  65.        { "EncodedByteAlign", &name_EncodedByteAlign },
  66.        { "Columns", &name_Columns },
  67.        { "Rows", &name_Rows },
  68.        { "EndOfBlock", &name_EndOfBlock },
  69.        { "BlackIs1", &name_BlackIs1 },
  70.        { "DamagedRowsBeforeError", &name_DamagedRowsBeforeError },
  71.        { "FirstBitLowOrder", &name_FirstBitLowOrder },
  72.  
  73.     /* Create the names of the (additional) known entries in */
  74.     /* CCITTFax filter dictionaries. */
  75.        { "Colors", &name_Colors },
  76.        { "HSamples", &name_HSamples },
  77.        { "VSamples", &name_VSamples },
  78.        { "QuantTables", &name_QuantTables },
  79.        { "QFactor", &name_QFactor },
  80.        { "HuffTables", &name_HuffTables },
  81.        { "ColorTransform", &name_ColorTransform },
  82.  
  83.     /* Mark the end of the initialized name list. */
  84.        names_def_end
  85.     };
  86.  
  87.     init_names(f2n);
  88. }
  89.  
  90. /* ------ ASCII85 filters ------ */
  91.  
  92. /* <target> .filter_ASCII85Encode <file> */
  93. extern const stream_procs s_A85E_procs;
  94. int
  95. zA85E(os_ptr op)
  96. {    return filter_write(op, &s_A85E_procs, NULL, 0);
  97. }
  98.  
  99. /* <source> .filter_ASCII85Decode <file> */
  100. extern const stream_procs s_A85D_procs;
  101. int
  102. zA85D(os_ptr op)
  103. {    return filter_read(op, &s_A85D_procs, NULL, 0);
  104. }
  105.  
  106. /* ------ CCITTFax filters ------ */
  107.  
  108. /* Common setup for encoding and decoding filters. */
  109. private int
  110. cf_setup(os_ptr op, CCITTFax_state *pcfs)
  111. {    int code;
  112.     check_type(*op, t_dictionary);
  113.     check_dict_read(*op);
  114.     if ( (code = dict_bool_param(op, &name_Uncompressed, 0,
  115.                      &pcfs->Uncompressed)) < 0 ||
  116.          (code = dict_int_param(op, &name_K, -9999, 9999, 0,
  117.                     &pcfs->K)) < 0 ||
  118.          (code = dict_bool_param(op, &name_EndOfLine, 0,
  119.                      &pcfs->EndOfLine)) < 0 ||
  120.          (code = dict_bool_param(op, &name_EncodedByteAlign, 0,
  121.                      &pcfs->EncodedByteAlign)) < 0 ||
  122.          (code = dict_int_param(op, &name_Columns, 0, 9999, 1728,
  123.                     &pcfs->Columns)) < 0 ||
  124.          (code = dict_int_param(op, &name_Rows, 0, 9999, 0,
  125.                     &pcfs->Rows)) < 0 ||
  126.          (code = dict_bool_param(op, &name_EndOfBlock, 1,
  127.                      &pcfs->EndOfBlock)) < 0 ||
  128.          (code = dict_bool_param(op, &name_BlackIs1, 0,
  129.                      &pcfs->BlackIs1)) < 0 ||
  130.          (code = dict_int_param(op, &name_DamagedRowsBeforeError, 0, 9999,
  131.                     0, &pcfs->DamagedRowsBeforeError)) < 0 ||
  132.          (code = dict_bool_param(op, &name_FirstBitLowOrder, 0,
  133.                      &pcfs->FirstBitLowOrder)) < 0
  134.        )
  135.         return code;
  136.     pcfs->raster = (pcfs->Columns + 7) >> 3;
  137.     return 0;
  138. }
  139.  
  140. /* <target> <dict> .filter_CCITTFaxEncode <file> */
  141. extern const stream_procs s_CFE_procs;
  142. extern void s_CFE_init(P2(stream *, CCITTFax_state *));
  143. int
  144. zCFE(os_ptr op)
  145. {    CCITTFax_state cfs;
  146.     stream *s;
  147.     int code = cf_setup(op, &cfs);
  148.     if ( code < 0 ) return code;
  149.     /* We need room for 2 full scan lines + 1 byte to handle 2-D. */
  150.     code = filter_write(op - 1, &s_CFE_procs, &s, cfs.raster * 2 + 1);
  151.     if ( code < 0 ) return code;
  152.     s_CFE_init(s, &cfs);
  153.     pop(1);
  154.     return 0;
  155. }
  156.  
  157. /* <source> <dict> .filter_CCITTFaxDecode <file> */
  158. extern const stream_procs s_CFD_procs;
  159. extern void s_CFD_init(P2(stream *, CCITTFax_state *));
  160. int
  161. zCFD(os_ptr op)
  162. {    CCITTFax_state cfs;
  163.     stream *s;
  164.     int code = cf_setup(op, &cfs);
  165.     if ( code < 0 ) return code;
  166.     /* We need room for 3 full scan lines to handle 2-D. */
  167.     code = filter_read(op - 1, &s_CFD_procs, &s, cfs.raster * 3 + 1);
  168.     if ( code < 0 ) return code;
  169.     s_CFD_init(s, &cfs);
  170.     pop(1);
  171.     return 0;
  172. }
  173.  
  174. /* ------ DCT filters ------ */
  175.  
  176. /* Common setup for encoding and decoding filters. */
  177. private int
  178. dct_setup_samples(os_ptr op, const ref *pname, int num_colors,
  179.   dct_color_params *params, int hvi)
  180. {    int code;
  181.     int i;
  182.     int samples[4];
  183.     samples[0] = samples[1] = samples[2] = samples[3] = 1;
  184.     if ( (code = dict_int_array_param(op, pname, num_colors, samples)) < 0 )
  185.         return code;
  186.     else if ( code != 0 && code != num_colors )
  187.         return_error(e_rangecheck);
  188.     for ( i = 0; i < num_colors; i++ )
  189.     {    if ( samples[i] < 1 || samples[i] > 4 )
  190.             return_error(e_rangecheck);
  191.         params[i].HVSamples[hvi] = samples[i];
  192.     }
  193.     return 0;
  194. }
  195. private int
  196. dct_setup(os_ptr op, DCT_state *pdct)
  197. {    int code;
  198.     int num_colors;
  199.     dct_color_params dcp[4];
  200.     check_type(*op, t_dictionary);
  201.     check_dict_read(*op);
  202.     if ( (code = dict_int_param(op, &name_Columns, 0, 0x7fff, -1,
  203.                     &pdct->Columns)) < 0 ||
  204.          (code = dict_int_param(op, &name_Rows, 0, 0x7fff, -1,
  205.                     &pdct->Rows)) < 0 ||
  206.          (code = dict_int_param(op, &name_Colors, 1, 4, -1,
  207.                     &num_colors)) < 0 ||
  208.          (code = dct_setup_samples(op, &name_HSamples, num_colors,
  209.                        dcp, 0)) < 0 ||
  210.          (code = dct_setup_samples(op, &name_VSamples, num_colors,
  211.                        dcp, 1)) < 0 ||
  212.          (code = dict_float_param(op, &name_QFactor, 1.0,
  213.                       &pdct->QFactor)) < 0 ||
  214.          (code = dict_int_param(op, &name_ColorTransform, 0, 1, 0,
  215.                     &pdct->ColorTransform)) < 0
  216.        )
  217.         return code;
  218.     pdct->Colors = num_colors;
  219.     /****** QuantTables are NYI ******/
  220.     /****** HuffTables are NYI ******/
  221.     pdct->params = (dct_color_params *)alloc(num_colors,
  222.                 sizeof(dct_color_params),
  223.                 "dct_setup(params)");
  224.     if ( pdct->params == 0 )
  225.         return_error(e_VMerror);
  226.     memcpy(pdct->params, dcp, num_colors * sizeof(dct_color_params));
  227.     return 0;
  228. }
  229.  
  230. /* <target> <dict> .filter_DCTEncode <file> */
  231. extern const stream_procs s_DCTE_procs;
  232. extern void s_DCTE_init(P2(stream *, DCT_state *));
  233. int
  234. zDCTE(os_ptr op)
  235. {    DCT_state dcts;
  236.     stream *s;
  237.     int code = dct_setup(op, &dcts);
  238.     if ( code < 0 ) return code;
  239.     code = filter_write(op - 1, &s_DCTE_procs, &s, 0);
  240.     if ( code < 0 )
  241.     {    /****** RELEASE STUFF ******/
  242.         return code;
  243.     }
  244.     s_DCTE_init(s, &dcts);
  245.     pop(1);
  246.     return 0;
  247. }
  248.  
  249. /* <source> <dict> .filter_DCTDecode <file> */
  250. extern const stream_procs s_DCTD_procs;
  251. extern void s_DCTD_init(P2(stream *, DCT_state *));
  252. int
  253. zDCTD(os_ptr op)
  254. {    DCT_state dcts;
  255.     stream *s;
  256.     int code = dct_setup(op, &dcts);
  257.     if ( code < 0 ) return code;
  258.     code = filter_read(op - 1, &s_DCTD_procs, &s, 0);
  259.     {    /****** RELEASE STUFF ******/
  260.         return code;
  261.     }
  262.     s_DCTD_init(s, &dcts);
  263.     pop(1);
  264.     return 0;
  265. }
  266.  
  267. /* ------ LZW filters ------ */
  268.  
  269. /* <target> .filter_LZWEncode <file> */
  270. extern const stream_procs s_LZWE_procs;
  271. extern const uint s_LZWE_table_sizeof;
  272. typedef struct lzw_encode_table_s lzw_encode_table;
  273. extern void s_LZWE_init(P3(stream *, lzw_encode_table *, int));
  274. int
  275. zLZWE_open(os_ptr op, int enhanced)
  276. {    stream *s;
  277.     int code = filter_write(op, &s_LZWE_procs, &s, 0);
  278.     lzw_encode_table *table;
  279.     if ( code < 0 ) return code;
  280.     table = (lzw_encode_table *)alloc(1, s_LZWE_table_sizeof,
  281.                       "filterLZWEncode(table)");
  282.     if ( table == 0 )
  283.         return_error(e_VMerror);
  284.     s_LZWE_init(s, table, enhanced);
  285.     return code;
  286. }
  287. int
  288. zLZWE(os_ptr op)
  289. {    return zLZWE_open(op, 0);
  290. }
  291. int
  292. zALZWE(os_ptr op)
  293. {    return zLZWE_open(op, 1);
  294. }
  295.  
  296. /* <source> .filter_LZWDecode <file> */
  297. extern const stream_procs s_LZWD_procs;
  298. extern const uint s_LZWD_table_sizeof;
  299. typedef struct lzw_decode_table_s lzw_decode_table;
  300. extern void s_LZWD_init(P3(stream *, lzw_decode_table *, int));
  301. int
  302. zLZWD_open(os_ptr op, int enhanced)
  303. {    stream *s;
  304.     int code = filter_read(op, &s_LZWD_procs, &s, 0);
  305.     lzw_decode_table *table;
  306.     if ( code < 0 ) return code;
  307.     table = (lzw_decode_table *)alloc(1, s_LZWD_table_sizeof,
  308.                       "filterLZWDecode(table)");
  309.     if ( table == 0 )
  310.         return_error(e_VMerror);
  311.     s_LZWD_init(s, table, enhanced);
  312.     return 0;
  313. }
  314. int
  315. zLZWD(os_ptr op)
  316. {    return zLZWD_open(op, 0);
  317. }
  318. int
  319. zALZWD(os_ptr op)
  320. {    return zLZWD_open(op, 1);
  321. }
  322.  
  323. /* ------ RunLength filters ------ */
  324.  
  325. /* <target> <record_size> .filter_RunLengthEncode <file> */
  326. extern const stream_procs s_RLE_procs;
  327. extern void s_RLE_init(P2(stream *, uint));
  328. int
  329. zRLE(register os_ptr op)
  330. {    stream *s;
  331.     int code;
  332.     check_type(*op, t_integer);
  333.     if ( (ulong)(op->value.intval) > max_uint )
  334.         return_error(e_rangecheck);
  335.     code = filter_write(op - 1, &s_RLE_procs, &s, 0);
  336.     if ( code < 0 )
  337.         return code;
  338.     s_RLE_init(s, (uint)(op->value.intval));
  339.     pop(1);
  340.     return 0;
  341. }
  342.  
  343. /* <source> .filter_RunLengthDecode <file> */
  344. extern const stream_procs s_RLD_procs;
  345. extern void s_RLD_init(P1(stream *));
  346. int
  347. zRLD(os_ptr op)
  348. {    stream *s;
  349.     int code = filter_read(op, &s_RLD_procs, &s, 0);
  350.     if ( code < 0 ) return code;
  351.     s_RLD_init(s);
  352.     return 0;
  353. }
  354.  
  355. /* ------ Initialization procedure ------ */
  356.  
  357. op_def zfilter2_op_defs[] = {
  358.     {"1.filter_ASCII85Encode", zA85E},
  359.     {"1.filter_ASCII85Decode", zA85D},
  360.     {"2.filter_CCITTFaxEncode", zCFE},
  361.     {"2.filter_CCITTFaxDecode", zCFD},
  362. #if 0            /* NYI */
  363.     {"2.filter_DCTEncode", zDCTE},
  364.     {"2.filter_DCTDecode", zDCTD},
  365. #endif
  366.     {"1.filter_LZWDecode", zLZWD},
  367.     {"1.filter_LZWEncode", zLZWE},
  368.     {"2.filter_RunLengthEncode", zRLE},
  369.     {"1.filter_RunLengthDecode", zRLD},
  370.     op_def_end(zfilter2_init)
  371. };
  372.